package org.domon.manager.base.mybatis.sql;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.jdbc.SQL;
import org.domon.manager.base.mybatis.MyBatisPojo;

/**
 * 获取基本CRUD的sql
 * 
 * @author Domon.Xie
 * 
 * @param <T>
 */
public class CRUDTemplate<T extends MyBatisPojo> {

	/**
	 * 用于存放每个实体insert sql，避免每次重新生成
	 */
	protected final static Map<Class<? extends MyBatisPojo>, String> insertSQL = new HashMap<Class<? extends MyBatisPojo>, String>();

	/**
	 * 新增
	 * 
	 * @param entity
	 * @return
	 */
	public String insert(T entity) {
		if (StringUtils.isNotBlank(insertSQL.get(entity.getClass()))) {
			return insertSQL.get(entity.getClass());
		}

		TableStructure table = entity.getTable();
		SQL sql = new SQL();
		sql.INSERT_INTO(table.getTableName());

		StringBuffer temp = new StringBuffer();
		for (Map.Entry<String, String> ent : table.getColumns().entrySet()) {
			temp.append("#{").append(ent.getKey()).append("}");
			sql.VALUES(ent.getValue(), temp.toString());
			temp.delete(0, temp.length());
		}

		insertSQL.put(entity.getClass(), sql.toString());
		return sql.toString();
	}

	/**
	 * 根据条件：MyBatisPojo.conditionField删除<br/>
	 * <li>如果MyBatisPojo.conditionField为空则默认以主键ID为条件</li>
	 * 
	 * @param entity
	 * @return
	 */
	public String delete(T entity) {
		TableStructure table = entity.getTable();

		SQL sql = new SQL();
		sql.DELETE_FROM(table.getTableName());
		sql.WHERE(getWhereColumn(entity));
		return sql.toString();
	}

	/**
	 * 根据条件：MyBatisPojo主键@ID删除<br/>
	 * <li>如果MyBatisPojo.conditionField为空则默认以主键ID为条件</li>
	 * 
	 * @param entity
	 * @return
	 */
	public String deleteById(T entity) {
		TableStructure table = entity.getTable();

		entity.setWhereField(table.getId());
		return delete(entity);
	}

	/**
	 * 根据条件：MyBatisPojo.conditionField修改MyBatisPojo.updateField的属性值<br/>
	 * <li>如果MyBatisPojo.conditionField为空则默认以主键ID为条件</li>
	 * 
	 * @param entity
	 * @return
	 */
	public String update(T entity) {
		TableStructure table = entity.getTable();

		SQL sql = new SQL();
		sql.UPDATE(table.getTableName());
		sql.SET(getUpdateColumn(entity));
		sql.WHERE(getWhereColumn(entity));
		return sql.toString();
	}

	/**
	 * 根据条件：MyBatisPojo主键@ID修改MyBatisPojo.updateField的属性值<br/>
	 * <li>如果MyBatisPojo.conditionField为空则默认以主键ID为条件</li>
	 * 
	 * @param entity
	 * @return
	 */
	public String updateById(T entity) {
		TableStructure table = entity.getTable();

		entity.setWhereField(table.getId());
		return update(entity);
	}

	/**
	 * 根据条件：MyBatisPojo.conditionField查询MyBatisPojo.selectResultField数据<br/>
	 * <li>如果MyBatisPojo.conditionField为空则默认以主键ID为条件</li> <li>
	 * 如果MyBatisPojo.selectResultField为空则默认查全部字段</li>
	 * 
	 * @param entity
	 * @return
	 */
	public String select(T entity) {
		TableStructure table = entity.getTable();

		SQL sql = new SQL();
		sql.SELECT(getSelectResultColumn(entity));
		sql.FROM(table.getTableName());
		sql.WHERE(getWhereColumn(entity));

		String orderColumn = getOrderColumn(entity);
		if (StringUtils.isNotBlank(orderColumn)) {
			sql.ORDER_BY(getOrderColumn(entity));
		}

		return sql.toString();
	}

	/**
	 * 根据条件：MyBatisPojo主键@ID查询MyBatisPojo.selectResultField数据<br/>
	 * <li>如果MyBatisPojo.selectResultField为空则默认查全部字段</li>
	 * 
	 * @param entity
	 * @return
	 */
	public String selectById(T entity) {
		TableStructure table = entity.getTable();

		entity.setWhereField(table.getId());
		return select(entity);
	}

	/**
	 * 获取delete/update/select的条件sql
	 * 
	 * @param entity
	 * @return
	 */
	private String getWhereColumn(T entity) {
		TableStructure table = entity.getTable();

		StringBuffer temp = new StringBuffer("1=1 ");
		for (int i = 0; i < entity.getWhereField().length; i++) {
			temp.append("AND ");
			temp.append(table.getColumns().get(entity.getWhereField()[i]));
			temp.append(entity.getWhereFieldChar()[i]);
			temp.append("#{").append(entity.getWhereField()[i]).append("} ");
		}

		return temp.toString();
	}

	/**
	 * 获取update修改值的sql
	 * 
	 * @param entity
	 * @return
	 */
	private String getUpdateColumn(T entity) {
		TableStructure table = entity.getTable();

		// 为空则修改全部字段
		if (entity.getUpdateField().length == 0) {
			for (Map.Entry<String, String> ent : table.getColumns().entrySet()) {
				// 数据创建时间和创建者不允许修改
				if (!StringUtils.equals(ent.getKey(), "crtBy") && !StringUtils.equals(ent.getKey(), "crtTime")) {
					entity.setUpdateField(ent.getKey());
				}
			}
		}

		StringBuffer temp = new StringBuffer();
		for (int i = 0; i < entity.getUpdateField().length; i++) {
			temp.append(table.getColumns().get(entity.getUpdateField()[i]));
			temp.append("=#{").append(entity.getUpdateField()[i]).append("}");

			if (i != entity.getUpdateField().length - 1) {
				temp.append(", ");
			}
		}

		return temp.toString();
	}

	/**
	 * 获取select结果集的sql
	 * 
	 * @param entity
	 * @return
	 */
	private String getSelectResultColumn(T entity) {
		TableStructure table = entity.getTable();

		StringBuffer temp = new StringBuffer();
		for (int i = 0; i < entity.getSelectResultField().length; i++) {
			temp.append(table.getColumns().get(entity.getSelectResultField()[i]));

			if (i != entity.getSelectResultField().length - 1) {
				temp.append(", ");
			}
		}

		// 为空则默认查询所有字段
		if (StringUtils.isBlank(temp.toString())) {
			temp.append("*");
		}
		return temp.toString();
	}

	private String getOrderColumn(T entity) {
		TableStructure table = entity.getTable();

		StringBuffer temp = new StringBuffer();
		for (int i = 0; i < entity.getOrderField().length; i++) {
			temp.append(table.getColumns().get(entity.getOrderField()[i]));

			if (i != entity.getSelectResultField().length - 1) {
				temp.append(", ");
			}
		}
		return temp.toString();
	}
}
